<?php
namespace app\nadmin\controller;
use app\nadmin\model\Adminer_M;
use app\nadmin\model\Menu_M;
use think\Validate;
use app\nadmin\model\Role_M;

/**
 * @explain 角色相关操作类
 * @time 2019/3/28
 * @writer liuhao
 */

class Role extends Base
{

    //模型实例
    protected $role_M;
    //每页记录数 默认为10
    protected $perpage = 10;

    //初始化模型
    protected function initialize()
    {
        $this->role_M = new Role_M();
    }

    /*
     * @explain 列表页
     */
    public function index()
    {
        return $this->fetch();
    }

    //加载列表数据
    public function getRoleList()
    {

        //页码
        $page = $this->request->page?$this->request->page:1; //页码
        $perpage = $this->request->limit ? $this->request->limit :$this->perpage; //每页记录数
        //数据验证
        $rule = [
            'page' => 'integer|gt:0|number',
            'perpage' => 'integer|gt:0',
        ];
        $msg = [
            'page.integer' => '页码参数必须为整数',
            'page.gt' => '页码参数必须大于0',
            'perpage.integer' => '每页记录数参数必须为整数',
            'perpage.gt' => '每页记录数参数必须大于0',
        ];
        $data = ['page'=>$page,'perpage'=>$perpage];
        $validate = Validate::make($rule,$msg);
        $re = $validate->check($data);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }

        $start = ($page-1) * $perpage;
        $limit = $start.','.$perpage;


        $field = "id,role,menu_ids,status";
        $list = $this->getMore($field,$where = [],$order = [],$limit);

        //获取角色下属成员
        if($list)
        {
            $adminerList = $this->roleMember($this->getRoleIds($list));
            //合并数据
            $list = $this->recombine($list,$adminerList);
        }

        //获取个数
        $count = $this->role_M->getCount();
        return laytable($count,$list);
    }

    //获取多条数据
    public function getMore($field='',$where = [],$order = [],$limit='')
    {
        $list = $this->role_M->getMore($field,$where = [],$order = [],$limit);
        return $list;
    }

    //编辑操作获取单个数据
    public function roleEdit()
    {
        $id = $this->request->id;
        $validate = Validate::make(['id'=>'integer|gt:0'],['id.integer'=>'参数异常 E001','id.gt'=>'参数异常 E002']);
        $re = $validate->check(['id'=>$id]);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        };

        $where = ['id'=>$id];
        $field = "id,role,status";
        $list = $this->role_M->getOne($field,$where);
        return echojson('success',1,$list);
    }

    //编辑操作
    public function doEdit()
    {
        //参数
        $id = $this->request->id;
        $status = $this->request->status;
        $role = $this->request->role;

        //验证
        $rule = [
            'id' => 'integer|gt:0|number',
            'status' => 'in:0,1',
            'role'=> 'require|chsDash|min:1|max:10', //汉字字母数字下划线
        ];
        $msg = [];
        $data = [
            'id'=>$id,
            'status'=>$status,
            'role'=>$role,
        ];
        $validate = Validate::make($rule,$msg);
        $re = $validate->check($data);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }

        $where = ['id'=>$id];
        $re = $this->role_M->editOne($data,$where);
        if($re){
            if($status == 0)
            {
                $this->adminerDisable($id); //角色下所有的管理员禁用
            }
            return echojson("修改成功",1);
        }else{
            return echojson("修改失败",0);
        }
    }

    //添加单条操作
    public function doAdd()
    {
        //参数
        $status = $this->request->status;
        $role = $this->request->role;

        //验证
        $rule = [
            'status' => 'in:0,1',
            'role'=> 'require|chsDash|min:1|max:10', //汉字字母数字下划线
        ];
        $msg = [];
        $data = [
            'status'=>$status,
            'role'=>$role,
        ];
        $validate = Validate::make($rule,$msg);
        $re = $validate->check($data);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }
        //操作
        $re = $this->role_M->insertOne($data);
        if($re){
            return echojson("添加成功",1);
        }else{
            return echojson("添加失败",0);
        }
    }
    //编辑 状态操作
    public function changeStatus()
    {
        //参数
        $id = $this->request->id;
        $status = $this->request->status;
        //验证参数
        $rule = [
            'id' => 'integer|gt:0|number',
            'status' => 'in:0,1',
        ];
        $msg = [
            'id.integer' => '参数ID必须为整数',
            'id.gt '=> '参数ID必须大于0',
            'status.in' => '参数status只能为0,1之间',
        ];
        $data = [
            'id' => $id,
            'status' => $status,
        ];

        $validate = Validate::make($rule,$msg);
        $re = $validate->check($data);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }

        //编辑
        $where = ['id'=>$id];
        $data = ['status'=>$status];
        $result = $this->role_M->editOne($data,$where);
        if($result)
        {
            if($status == 0)
            {
                $this->adminerDisable($id); //角色下所有的管理员禁用
            }
            return echojson("修改成功",1);
        }else{
            return echojson("修改失败",0);
        }
    }

    //删除单条记录
    public function delOne()
    {
        $id = $this->request->id;
        //验证数据
        $validate = Validate::make(['id' => 'integer|gt:0'],[]);
        $re = $validate->check(['id'=>$id]);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }

        $where = ['id'=>$id];
        $result = $this->role_M->delOne($where);
        if($result)
        {
            return echojson('删除成功',1);
        }else{
            return echojson('删除失败',0);
        }
    }
    //删除多条记录
    public function delMore()
    {
        $idStr = $this->request->idStr;
        //验证规则
        $rule = [
            'idStr' => ['regex' => '/^(([1-9]\d*)|(([1-9]\d*,)+[1-9]\d*))$/','require'],
        ];
        $validate = Validate::make($rule,[]);
        $re = $validate->check(['idStr'=>$idStr]);
        if(!$re)
        {
            return echojson($validate->getError(),0);
        }

        $where = "id in ($idStr)";
        $result = $this->role_M->delMore($where);
        if($result)
        {
            return echojson('删除成功',1);
        }else{
            return echojson('删除失败',0);
        }
    }

    /* @explain 获取角色下属成员
     * @param $RoleIds [] 角色id集合数据
     * @return []
     */
    protected function roleMember($RoleIds)
    {
        if(is_array($RoleIds) && $RoleIds)
        {
            $adminer = new Adminer_M();
            $filed = "id,role_id,username,status";
            $where = ['role_id'=>$RoleIds];
            $list = $adminer->getMore($filed,$where);
            return $list;
        }else{
            return [];
        }
    }

    /* @explain 从角色列表数据中抽取出ID
     * @param $list [] 角色列表数据
     * @return []
     */
    protected function getRoleIds($list)
    {
        if(is_array($list) && $list)
        {
            return array_column($list,'id');
        }
        return [];
    }

    /* @explain 将角色列表数据和所属管理员列表数据合并
     * @param $list []  角色数据列表 , $adminerList [] 管理员数据列表
     * @return []
     */
    protected function recombine($list,$adminerList)
    {
        if($list && $adminerList){
            foreach($list as &$v)
            {
                foreach($adminerList as $key=>$val)
                {
                    if($val['role_id'] == $v['id'])
                    {
                        $v['member'][] = $val;
                        unset($adminerList[$key]);
                    }
                }
            }
        }
        return $list;
    }

    /* @explain 若角色状态禁用，下属所有管理员将禁用
     * @param $role_id []|int 角色id或id集合
     */
    protected function adminerDisable($role_id)
    {
        $adminer = new Adminer_M();
        $data = ['status'=>0];
        $where = ['role_id'=>$role_id];
        $re = $adminer->editMore($data,$where);
        return $re;
    }

    /*
     * @explain 查询所有角色数据，并完成树形结构
     */
    public function getMenuTree()
    {
        $id = $this->request->id;
        $validate = Validate::make(['id'=>'require|gt:0'],[]);
        if(!$validate->check(['id'=>$id]))
        {
            return echojson($validate->getError(),0);
        }
        //当前角色的权限
        $menu_ids = $this->role_M->getOne("menu_ids",['id'=>$id]);


        $field = "id,title,pid,lev,d_type";
        $where = ['status'=>1];
        $menu = new Menu_M();
        $list = $menu->getMore($field,$where);
        $keys = array_column($list,'id');
        $list = array_combine($keys,$list);
        $list = $this->insertRoleStatus($list,$menu_ids['menu_ids']);//在菜单列表中插入某角色是否拥有权限

        //树形结构转换
        $list = getTree_1($list);

        return echojson('OK',1,$list);
    }


    /* 在菜单列表中插入某角色是否拥有权限
     * @param $list [] 菜单列表 ，$menu_ids str 该角色拥有的权限集合
     * @return []
     */
    protected function insertRoleStatus($list,$menu_ids)
    {
        if($menu_ids == '0')
        {
            //超级管理员
            array_walk($list,function(&$val){$val['status']=1;});
        }elseif($menu_ids == '-1'){
            //无任何权限
            array_walk($list,function(&$val){$val['status']=0;});
        }else{
            $menu_idsArr = explode(',',$menu_ids);
            foreach($list as $k=>&$v)
            {
                if(in_array($k,$menu_idsArr))
                {
                    $v['status'] = 1;
                }
            }
        }
        return $list;
    }

    /*分配权限操作*/
    public function roleAllot()
    {
        $id = $this->request->id; //角色ID
        $menuIdArr = $this->request->menu; //菜单id集合

        if(is_array($menuIdArr))
        {
            sort($menuIdArr);
            $menuIds = join(',',$menuIdArr);
        }else{
            return echojson('参数异常',0);
        }

        //验证
        $rule = [
            'id'=>'require|gt:0|number',
            'menuIds'=>['regex' => '/^(([1-9]\d*)|(([1-9]\d*,)+[1-9]\d*))$/'],
        ];
        $data = [
            'id'=>$id,
            'menuIds'=>$menuIds,
        ];
        $validate = Validate::make($rule,[]);
        if(!$validate->check($data))
        {
            return echojson($validate->getError(),0);
        }
        if($menuIds)
        {
            //判断是否超级管理员权限
            $menu = new Menu_M();
            $menuList = $menu->getMore("id","status=1");
            $menuList =array_column($menuList,'id');
            sort($menuList);
            $menu = join(',',$menuList);
            if($menu == $menuIds)
            {
                //选取了所有的菜单，超级管理员
                $menuIds = '0';
            }
        }else{
            $menuIds = '-1';
        }

        //修改权限
        $re = $this->role_M->editOne(['menu_ids'=>$menuIds],['id'=>$id]);
        if($re)
        {
            return echojson('权限分配成功',1);
        }else{
            return echojson('权限分配失败',0);
        }
    }

}